package java基础语法练习;

import sun.misc.Unsafe;

import java.lang.reflect.Field;

/**
 * @author caihe
 * @date 2021/10/20 10:06
 */
public class ExampleObj {

    private static final Unsafe unsafe = reflectGetUnsafe();

    public volatile int state;

    public volatile String des;

    private static long stateOffset;

//    public static final long desOffset;

    /**
     * objectFieldOffset 返回对象成员属性在内存地址相对于此对象的内存地址的偏移量
     * 
     */
    static {
        try {
            stateOffset = reflectGetUnsafe().objectFieldOffset(ExampleObj.class.getDeclaredField("state"));
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
    
    public void changeValue(long offset, int exp, int upd) {
        System.out.println(unsafe.compareAndSwapInt(this, offset, exp, upd));
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    public String getDes() {
        return des;
    }

    public void setDes(String des) {
        this.des = des;
    }

    public static long getStateOffset() {
        return stateOffset;
    }

    public static void setStateOffset(long stateOffset) {
        ExampleObj.stateOffset = stateOffset;
    }

    /**
     * 通过反射获取 Unsafe demo2
     *
     * @return
     */
    public static Unsafe reflectGetUnsafe() {
        try {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            return (Unsafe) field.get(null);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 通过反射获取 Unsafe demo1
     *
     * @return
     */
    private static Unsafe getUnsafe()  {
        Class<?> unsafeClass = Unsafe.class;
        for (Field f : unsafeClass.getDeclaredFields()) {
            if ("theUnsafe".equals(f.getName())) {
                f.setAccessible(true);
                try {
                    return (Unsafe) f.get(null);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}
